#!/bin/bash
# Author: fanyongfeng
# 安装Zookeeper 单节点
# 操作系统：centos7/银河麒麟v10

set -e
# 使用root用户执行
[[ $(id -u) -ne 0 ]] && echo "请使用root用户执行此脚本" && exit 1

usage(){
    echo "Usage:"
    echo "sh $0
            --prefix=安装目录(默认/data/zookeeper-\$VERSION)
            --version=zookeeper版本(默认3.7.0)
        "
    echo "示例:"
    echo "sh $0 --version=3.7.0"
    exit 1
}

#处理参数，规范化参数
ARGS=$(getopt -o h --long prefix:,version:,mode:,help -n "$0" -- "$@")

if [[ $? != 0 || $# -eq 0 ]]
then
        usage
fi

#重新排列参数顺序
eval set -- "${ARGS}"
#通过shift和while循环处理参数
while true
do
    case $1 in
        --prefix)
            PREFIX=$2
            shift 2
            ;;
        --version)
            VERSION=$2
            shift 2
            ;;
        -h|--help)
            usage
            exit 1
            ;;
        --)
           shift
           break
           ;;
        *)
           echo "Internal error!"
           exit 1
           ;;
    esac
done

# 检查java环境
[[ $JAVA_HOME == "" ]] && echo "未找到环境变量\${JAVA_HOME},请先配置java环境." && exit 1

VERSION=${VERSION:-3.7.0}
INSTALL_DIR="/data/zookeeper-${VERSION}"
DATA_DIR="${INSTALL_DIR}/data"
RUN_USER="zk"
HOST_IP=$(ip a | grep global | head -1 | awk -F'/' '{print $1}' | awk '{print $2}')
 
# 关闭防火墙和selinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce  0

# 下载安装包
[[ -f apache-zookeeper-${VERSION}-bin.tar.gz ]] || wget https://archive.apache.org/dist/zookeeper/zookeeper-${VERSION}/apache-zookeeper-${VERSION}-bin.tar.gz
if [[ $? -ne 0 ]]
then
    echo "apache-zookeeper-${VERSION}-bin.tar.gz下载失败，请重试或手动上传此安装包"
    exit 1
fi

# 解压安装包
tar zxf apache-zookeeper-${VERSION}-bin.tar.gz && mv apache-zookeeper-${VERSION}-bin ${INSTALL_DIR}
 
# 添加配置文件zoo.cfg
cat > ${INSTALL_DIR}/conf/zoo.cfg << EOF
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=${DATA_DIR}
dataLogDir=${INSTALL_DIR}/logs
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
maxClientCnxns=1000
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
admin.enableServer = false
admin.serverAddress = ${HOST_IP}
admin.serverPort = 8080
# The number of snapshots to retain in dataDir
autopurge.snapRetainCount=10
# Purge task interval in hours
# Set to "0" to disable auto purge feature
autopurge.purgeInterval=1
 
# 集群模式
# server.1=zookeeper1:2888:3888
# server.2=zookeeper2:2888:3888
# server.3=zookeeper3:2888:3888
 
# 配置4字命令白名单
4lw.commands.whitelist=ruok, stat, envi
EOF

# 添加用户
useradd ${RUN_USER} -s /sbin/nologin
mkdir -p ${DATA_DIR}
chown -R ${RUN_USER}.${RUN_USER} ${INSTALL_DIR} ${DATA_DIR}

# 使用systemd管理
cat > /etc/systemd/system/zookeeper.service << EOF
[Unit]
# 服务描述
Description=zookeeper service
Requires=network.service
After=network.target
 
[Service]
User=${RUN_USER}
Group=${RUN_USER}
Type=forking
Environment=JAVA_HOME=$JAVA_HOME
ExecStart=${INSTALL_DIR}/bin/zkServer.sh start
ExecStop=${INSTALL_DIR}/bin/zkServer.sh stop
ExecReload=${INSTALL_DIR}/bin/zkServer.sh restart
PIDFile=${DATA_DIR}/zookeeper_server.pid
KillMode=none
Restart=on-failure
RestartSec=30s
 
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable zookeeper
systemctl start zookeeper
sleep 2
systemctl status zookeeper